package com.cencat.product.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cencat.product.dto.ProductQueryDTO;
import com.cencat.product.entity.Product;
import com.cencat.product.vo.ProductVO;
import org.apache.ibatis.annotations.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 产品数据访问层
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Mapper
public interface ProductMapper extends BaseMapper<Product> {

    /**
     * 根据产品编码查询产品
     * 
     * @param productCode 产品编码
     * @return 产品信息
     */
    @Select("SELECT * FROM product WHERE product_code = #{productCode} AND deleted = 0")
    Product selectByProductCode(@Param("productCode") String productCode);

    /**
     * 根据产品名称查询产品
     * 
     * @param productName 产品名称
     * @return 产品信息
     */
    @Select("SELECT * FROM product WHERE product_name = #{productName} AND deleted = 0")
    Product selectByProductName(@Param("productName") String productName);

    /**
     * 根据商家ID查询产品列表
     * 
     * @param merchantId 商家ID
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE merchant_id = #{merchantId} AND deleted = 0 ORDER BY create_time DESC")
    List<Product> selectByMerchantId(@Param("merchantId") Long merchantId);

    /**
     * 根据分类ID查询产品列表
     * 
     * @param categoryId 分类ID
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE category_id = #{categoryId} AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<Product> selectByCategoryId(@Param("categoryId") Long categoryId);

    /**
     * 根据品牌ID查询产品列表
     * 
     * @param brandId 品牌ID
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE brand_id = #{brandId} AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<Product> selectByBrandId(@Param("brandId") Long brandId);

    /**
     * 分页查询产品列表
     * 
     * @param page 分页参数
     * @param queryDTO 查询条件
     * @return 产品分页列表
     */
    IPage<ProductVO> selectProductPage(IPage<ProductVO> page, @Param("query") ProductQueryDTO queryDTO);

    /**
     * 查询产品详情
     * 
     * @param id 产品ID
     * @return 产品详情
     */
    ProductVO selectProductDetail(@Param("id") Long id);

    /**
     * 根据产品类型查询产品列表
     * 
     * @param productType 产品类型
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE product_type = #{productType} AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<Product> selectByProductType(@Param("productType") Product.ProductType productType);

    /**
     * 根据产品状态查询产品列表
     * 
     * @param status 产品状态
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE status = #{status} AND deleted = 0 ORDER BY sort_order ASC, create_time DESC")
    List<Product> selectByStatus(@Param("status") Product.ProductStatus status);

    /**
     * 根据审核状态查询产品列表
     * 
     * @param auditStatus 审核状态
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE audit_status = #{auditStatus} AND deleted = 0 ORDER BY create_time DESC")
    List<Product> selectByAuditStatus(@Param("auditStatus") Product.AuditStatus auditStatus);

    /**
     * 查询推荐产品列表
     * 
     * @param limit 限制数量
     * @return 推荐产品列表
     */
    @Select("SELECT * FROM product WHERE is_recommended = 1 AND status = 'ON_SHELF' AND deleted = 0 ORDER BY sort_order ASC, create_time DESC LIMIT #{limit}")
    List<Product> selectRecommendedProducts(@Param("limit") Integer limit);

    /**
     * 查询热销产品列表
     * 
     * @param limit 限制数量
     * @return 热销产品列表
     */
    @Select("SELECT * FROM product WHERE is_hot = 1 AND status = 'ON_SHELF' AND deleted = 0 ORDER BY sales_count DESC, sort_order ASC LIMIT #{limit}")
    List<Product> selectHotProducts(@Param("limit") Integer limit);

    /**
     * 查询新品列表
     * 
     * @param limit 限制数量
     * @return 新品列表
     */
    @Select("SELECT * FROM product WHERE is_new = 1 AND status = 'ON_SHELF' AND deleted = 0 ORDER BY create_time DESC LIMIT #{limit}")
    List<Product> selectNewProducts(@Param("limit") Integer limit);

    /**
     * 查询特价产品列表
     * 
     * @param limit 限制数量
     * @return 特价产品列表
     */
    @Select("SELECT * FROM product WHERE is_special = 1 AND status = 'ON_SHELF' AND deleted = 0 ORDER BY sort_order ASC, create_time DESC LIMIT #{limit}")
    List<Product> selectSpecialProducts(@Param("limit") Integer limit);

    /**
     * 统计产品总数
     * 
     * @return 产品总数
     */
    @Select("SELECT COUNT(*) FROM product WHERE deleted = 0")
    Long countTotal();

    /**
     * 根据状态统计产品数量
     * 
     * @param status 产品状态
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE status = #{status} AND deleted = 0")
    Long countByStatus(@Param("status") Product.ProductStatus status);

    /**
     * 根据产品类型统计产品数量
     * 
     * @param productType 产品类型
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE product_type = #{productType} AND deleted = 0")
    Long countByProductType(@Param("productType") Product.ProductType productType);

    /**
     * 根据审核状态统计产品数量
     * 
     * @param auditStatus 审核状态
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE audit_status = #{auditStatus} AND deleted = 0")
    Long countByAuditStatus(@Param("auditStatus") Product.AuditStatus auditStatus);

    /**
     * 根据商家ID统计产品数量
     * 
     * @param merchantId 商家ID
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE merchant_id = #{merchantId} AND deleted = 0")
    Long countByMerchantId(@Param("merchantId") Long merchantId);

    /**
     * 根据分类ID统计产品数量
     * 
     * @param categoryId 分类ID
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE category_id = #{categoryId} AND deleted = 0")
    Long countByCategoryId(@Param("categoryId") Long categoryId);

    /**
     * 根据品牌ID统计产品数量
     * 
     * @param brandId 品牌ID
     * @return 产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE brand_id = #{brandId} AND deleted = 0")
    Long countByBrandId(@Param("brandId") Long brandId);

    /**
     * 统计库存不足的产品数量
     * 
     * @return 库存不足产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE stock_quantity <= warning_stock AND deleted = 0")
    Long countLowStockProducts();

    /**
     * 统计售罄产品数量
     * 
     * @return 售罄产品数量
     */
    @Select("SELECT COUNT(*) FROM product WHERE stock_quantity = 0 AND deleted = 0")
    Long countSoldOutProducts();

    /**
     * 批量更新产品状态
     * 
     * @param ids 产品ID列表
     * @param status 产品状态
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET status = #{status}, update_by = #{updateBy}, update_time = NOW() WHERE id IN (${ids}) AND deleted = 0")
    int batchUpdateStatus(@Param("ids") String ids, @Param("status") Product.ProductStatus status, @Param("updateBy") Long updateBy);

    /**
     * 批量更新审核状态
     * 
     * @param ids 产品ID列表
     * @param auditStatus 审核状态
     * @param auditBy 审核人ID
     * @param auditRemark 审核备注
     * @return 更新数量
     */
    @Update("UPDATE product SET audit_status = #{auditStatus}, audit_by = #{auditBy}, audit_time = NOW(), audit_remark = #{auditRemark}, update_by = #{auditBy}, update_time = NOW() WHERE id IN (${ids}) AND deleted = 0")
    int batchUpdateAuditStatus(@Param("ids") String ids, @Param("auditStatus") Product.AuditStatus auditStatus, @Param("auditBy") Long auditBy, @Param("auditRemark") String auditRemark);

    /**
     * 批量上架产品
     * 
     * @param ids 产品ID列表
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET status = 'ON_SHELF', shelf_time = NOW(), update_by = #{updateBy}, update_time = NOW() WHERE id IN (${ids}) AND deleted = 0")
    int batchOnShelf(@Param("ids") String ids, @Param("updateBy") Long updateBy);

    /**
     * 批量下架产品
     * 
     * @param ids 产品ID列表
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET status = 'OFF_SHELF', off_shelf_time = NOW(), update_by = #{updateBy}, update_time = NOW() WHERE id IN (${ids}) AND deleted = 0")
    int batchOffShelf(@Param("ids") String ids, @Param("updateBy") Long updateBy);

    /**
     * 批量删除产品
     * 
     * @param ids 产品ID列表
     * @param updateBy 更新人ID
     * @return 删除数量
     */
    @Update("UPDATE product SET deleted = 1, update_by = #{updateBy}, update_time = NOW() WHERE id IN (${ids}) AND deleted = 0")
    int batchDelete(@Param("ids") String ids, @Param("updateBy") Long updateBy);

    /**
     * 更新产品库存
     * 
     * @param id 产品ID
     * @param stockQuantity 库存数量
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET stock_quantity = #{stockQuantity}, update_by = #{updateBy}, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int updateStock(@Param("id") Long id, @Param("stockQuantity") Integer stockQuantity, @Param("updateBy") Long updateBy);

    /**
     * 增加产品库存
     * 
     * @param id 产品ID
     * @param quantity 增加数量
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET stock_quantity = stock_quantity + #{quantity}, update_by = #{updateBy}, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int increaseStock(@Param("id") Long id, @Param("quantity") Integer quantity, @Param("updateBy") Long updateBy);

    /**
     * 减少产品库存
     * 
     * @param id 产品ID
     * @param quantity 减少数量
     * @param updateBy 更新人ID
     * @return 更新数量
     */
    @Update("UPDATE product SET stock_quantity = stock_quantity - #{quantity}, update_by = #{updateBy}, update_time = NOW() WHERE id = #{id} AND stock_quantity >= #{quantity} AND deleted = 0")
    int decreaseStock(@Param("id") Long id, @Param("quantity") Integer quantity, @Param("updateBy") Long updateBy);

    /**
     * 更新产品销售数量
     * 
     * @param id 产品ID
     * @param salesCount 销售数量
     * @return 更新数量
     */
    @Update("UPDATE product SET sales_count = sales_count + #{salesCount}, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int updateSalesCount(@Param("id") Long id, @Param("salesCount") Integer salesCount);

    /**
     * 更新产品浏览数量
     * 
     * @param id 产品ID
     * @return 更新数量
     */
    @Update("UPDATE product SET view_count = view_count + 1, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int updateViewCount(@Param("id") Long id);

    /**
     * 更新产品收藏数量
     * 
     * @param id 产品ID
     * @param favoriteCount 收藏数量变化（正数增加，负数减少）
     * @return 更新数量
     */
    @Update("UPDATE product SET favorite_count = favorite_count + #{favoriteCount}, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int updateFavoriteCount(@Param("id") Long id, @Param("favoriteCount") Integer favoriteCount);

    /**
     * 更新产品评分
     * 
     * @param id 产品ID
     * @param rating 评分
     * @param commentCount 评论数量
     * @return 更新数量
     */
    @Update("UPDATE product SET rating = #{rating}, comment_count = #{commentCount}, update_time = NOW() WHERE id = #{id} AND deleted = 0")
    int updateRating(@Param("id") Long id, @Param("rating") BigDecimal rating, @Param("commentCount") Integer commentCount);

    /**
     * 检查产品编码是否存在
     * 
     * @param productCode 产品编码
     * @param excludeId 排除的产品ID（用于更新时检查）
     * @return 是否存在
     */
    @Select("SELECT COUNT(*) > 0 FROM product WHERE product_code = #{productCode} AND id != #{excludeId} AND deleted = 0")
    boolean existsProductCode(@Param("productCode") String productCode, @Param("excludeId") Long excludeId);

    /**
     * 检查产品名称是否存在
     * 
     * @param productName 产品名称
     * @param excludeId 排除的产品ID（用于更新时检查）
     * @return 是否存在
     */
    @Select("SELECT COUNT(*) > 0 FROM product WHERE product_name = #{productName} AND id != #{excludeId} AND deleted = 0")
    boolean existsProductName(@Param("productName") String productName, @Param("excludeId") Long excludeId);

    /**
     * 获取下一个产品编码序号
     * 
     * @param prefix 编码前缀
     * @return 下一个序号
     */
    @Select("SELECT IFNULL(MAX(CAST(SUBSTRING(product_code, #{prefixLength} + 1) AS UNSIGNED)), 0) + 1 FROM product WHERE product_code LIKE CONCAT(#{prefix}, '%') AND deleted = 0")
    Long getNextProductCodeSequence(@Param("prefix") String prefix, @Param("prefixLength") Integer prefixLength);

    /**
     * 查询即将过期的产品
     * 
     * @param days 天数
     * @return 即将过期的产品列表
     */
    @Select("SELECT * FROM product WHERE expiry_date IS NOT NULL AND expiry_date <= DATE_ADD(NOW(), INTERVAL #{days} DAY) AND deleted = 0")
    List<Product> selectExpiringProducts(@Param("days") Integer days);

    /**
     * 查询已过期的产品
     * 
     * @return 已过期的产品列表
     */
    @Select("SELECT * FROM product WHERE expiry_date IS NOT NULL AND expiry_date < NOW() AND deleted = 0")
    List<Product> selectExpiredProducts();

    /**
     * 查询库存不足的产品
     * 
     * @return 库存不足的产品列表
     */
    @Select("SELECT * FROM product WHERE stock_quantity <= warning_stock AND deleted = 0")
    List<Product> selectLowStockProducts();

    /**
     * 查询售罄的产品
     * 
     * @return 售罄的产品列表
     */
    @Select("SELECT * FROM product WHERE stock_quantity = 0 AND deleted = 0")
    List<Product> selectSoldOutProducts();

    /**
     * 查询商家产品统计信息
     * 
     * @param merchantId 商家ID
     * @return 统计信息
     */
    Map<String, Object> selectMerchantProductStats(@Param("merchantId") Long merchantId);

    /**
     * 查询分类产品统计信息
     * 
     * @param categoryId 分类ID
     * @return 统计信息
     */
    Map<String, Object> selectCategoryProductStats(@Param("categoryId") Long categoryId);

    /**
     * 查询品牌产品统计信息
     * 
     * @param brandId 品牌ID
     * @return 统计信息
     */
    Map<String, Object> selectBrandProductStats(@Param("brandId") Long brandId);

    /**
     * 查询产品销售统计（按时间范围）
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 销售统计
     */
    List<Map<String, Object>> selectProductSalesStats(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);

    /**
     * 查询产品库存统计
     * 
     * @return 库存统计
     */
    Map<String, Object> selectProductStockStats();

    /**
     * 搜索产品（全文搜索）
     * 
     * @param keyword 关键词
     * @param limit 限制数量
     * @return 产品列表
     */
    List<Product> searchProducts(@Param("keyword") String keyword, @Param("limit") Integer limit);

    /**
     * 根据价格区间查询产品
     * 
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @return 产品列表
     */
    @Select("SELECT * FROM product WHERE sale_price >= #{minPrice} AND sale_price <= #{maxPrice} AND status = 'ON_SHELF' AND deleted = 0 ORDER BY sale_price ASC")
    List<Product> selectByPriceRange(@Param("minPrice") BigDecimal minPrice, @Param("maxPrice") BigDecimal maxPrice);

    /**
     * 查询相关产品（同分类或同品牌）
     * 
     * @param productId 产品ID
     * @param limit 限制数量
     * @return 相关产品列表
     */
    List<Product> selectRelatedProducts(@Param("productId") Long productId, @Param("limit") Integer limit);
}